package com.hksj.umm.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.hksj.base.query.DeviceOverviewQuery;
import com.hksj.base.service.DefaultDeviceService;
import com.hksj.base.vo.DeviceOverviewVO;
import com.hksj.cbm.dto.DeviceDTO;
import com.hksj.cbm.entity.DeviceInstance;
import com.hksj.cbm.service.DeviceInstanceService;
import com.hksj.cbm.vo.DeriveMetadataVO;
import com.hksj.cbm.vo.RuleSceneVO;
import com.hksj.common.core.common.SpecialityModelCodeEnum;
import com.hksj.common.core.util.DateUtil;
import com.hksj.umm.mapper.UVCockpitMapper;
import com.hksj.umm.query.UVCockpitQuery;
import com.hksj.umm.vo.UVDeviceOverviewVO;
import com.hksj.umm.vo.UVLightingDurationVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author fjt
 * @data 2024/11/4 17:29
 * @describe  紫外线灯——驾驶舱
 */
@Service
public class UVCockpitService {


    @Autowired
    private UVCockpitMapper cockpitMapper;
    @Autowired
    private DeviceInstanceService deviceInstanceService;



    /**
     * 定时控制策略查询
     * @return
     */
    public List<RuleSceneVO> queryScheduledTasks(String ruleType){
        return cockpitMapper.queryScheduledTasks(SpecialityModelCodeEnum.uv_lamp_control.getCode(), ruleType);
    }


    /**
     * 设备概览
     * @param query
     * @return
     */
    public UVDeviceOverviewVO deviceOverView(UVCockpitQuery query){
        // 查询符合要求的紫外线灯开关控制器设备
        DeviceDTO deviceDTO = DeviceDTO.builder().code(SpecialityModelCodeEnum.uv_lamp_control.getCode())
                .departmentItemValue(query.getDepartmentItemValue()).paths(query.getPaths()).build();
        List<DeviceInstance> deviceList = deviceInstanceService.deviceList(deviceDTO);
        if (CollUtil.isEmpty(deviceList)){
            return new UVDeviceOverviewVO();
        }

        UVDeviceOverviewVO overviewVO = new UVDeviceOverviewVO();
        // 在线
        List<DeviceInstance> onLineDeviceList = deviceList.stream().
                filter(device -> "online".equals(device.getState()))
                .collect(Collectors.toList());
        // 离线
        List<DeviceInstance> offLineDeviceList = deviceList.stream().
                filter(device -> "offline".equals(device.getState()))
                .collect(Collectors.toList());
        // 未激活
        List<DeviceInstance> notActiveList = deviceList.stream().
                filter(device -> "notActive".equals(device.getState()))
                .collect(Collectors.toList());
        overviewVO.setTotal(deviceList.size());
        overviewVO.setOnlineNum(CollUtil.isNotEmpty(onLineDeviceList) ? onLineDeviceList.size() : 0);
        overviewVO.setOfflineNum(CollUtil.isNotEmpty(offLineDeviceList) ? offLineDeviceList.size() : 0);
        overviewVO.setNotActiveNum(CollUtil.isNotEmpty(notActiveList) ? notActiveList.size() : 0);

        // 查询开关控制点位数量
        List<String> deviceIdList = deviceList.stream().map(DeviceInstance::getId).collect(Collectors.toList());
        // 设备id : <设备监测指标key : 指标相关信息>
        Map<String, Map<String, DeriveMetadataVO>> outMap = deviceInstanceService.batchQueryDeviceAttribute(deviceIdList);
        if (CollUtil.isEmpty(outMap.values())){
            overviewVO.setPointTotal(0);
            return overviewVO;
        }

        List<String> innerKeys = outMap.values().stream()
                .flatMap(innerMap -> innerMap.keySet().stream())
                .filter(key -> key.endsWith("dwzt"))
                .collect(Collectors.toList());

        overviewVO.setPointTotal(innerKeys.size());
        return overviewVO;
    }


    /**
     *
     * @param deviceIdList
     * @return 设备id-每个property的key : 每个key的中文名称
     */
    private Map<String, String> buildProperty(List<String> deviceIdList){
        // 设备id : <设备监测指标key : 指标相关信息>
        Map<String, Map<String, DeriveMetadataVO>> propertyMap = deviceInstanceService.batchQueryDeviceAttribute(deviceIdList);
        Map<String, String> propertyNameMap = new HashMap<>();
        for(Map.Entry<String, Map<String, DeriveMetadataVO>> entry : propertyMap.entrySet()){
            entry.getValue().forEach((k, v) -> {
                propertyNameMap.put(entry.getKey() + "-" + k, v.getKeyName());
            });
        }
        return propertyNameMap;
    }



    /**
     * 消杀记录（最近3天）   查询各回路每次消杀的明细记录
     * @param query
     * @return
     */
    public List<UVLightingDurationVO> LightingDurationDetail(UVCockpitQuery query){
        query.setCode(SpecialityModelCodeEnum.uv_lamp_control.getCode());
        query.setEndTime(DateUtil.convertToDate(LocalDateTime.now()));
        query.setStartTime(DateUtil.convertToDate(LocalDateTime.now().minusDays(3)));
        List<UVLightingDurationVO> durationVOList = cockpitMapper.queryLightingDurationDetail(query);
        if (CollUtil.isEmpty(durationVOList)){
            return null;
        }

        // 查询每个设备中，每个property的中文名称
        List<String> deviceIdList = durationVOList.stream().map(UVLightingDurationVO::getDeviceId).distinct().collect(Collectors.toList());
        // 设备id-每个property的key : 每个key的中文名称
        Map<String, String> propertyMap = buildProperty(deviceIdList);

        // 根据查询时间计算每支回路的消杀时长
        durationVOList.forEach(lightingDurationVO -> {
            checkLightingTime(lightingDurationVO, query.getStartTime(), query.getEndTime());
            lightingDurationVO.setPropertyName(propertyMap.get(lightingDurationVO.getDeviceId() + "-" + lightingDurationVO.getProperty()));
            // 时长单位：分钟
            lightingDurationVO.setDurationMinute(new BigDecimal(lightingDurationVO.getDurationLong()).divide(new BigDecimal(60), 2, BigDecimal.ROUND_HALF_UP));
        });

        // 按开启时间倒序
        return durationVOList.stream().sorted(Comparator.comparing(UVLightingDurationVO::getOpenTime, Comparator.reverseOrder())).collect(Collectors.toList());
    }


    /**
     * 根据查询时间校正每支回路的计算消杀时长的起止时间，并计算消杀时长(单位：秒)
     * 如：查询时间是8到9点整，则每个连续的消杀时长最多只有8到9点的这一个小时，超出的部分不属于当前查询时间范围内的照明时长，不参与消杀时长的计算(和产品确认过)
     * @param durationVO
     * @param queryStartTime
     * @param queryEndTime
     * @return
     */
    private void checkLightingTime(UVLightingDurationVO durationVO, Date queryStartTime, Date queryEndTime){
        // 计算开始时间
        Date startTime = null;
        Date openTime = durationVO.getOpenTime();
        Date closeTime = durationVO.getCloseTime();
        if (queryStartTime.compareTo(openTime) > 0){
            // 查询起始时间晚于openTime
            startTime = queryStartTime;
        }else {
            startTime = openTime;
        }

        // 计算截止时间
        Date endTime = null;
        if (ObjectUtil.isNotNull(closeTime) && queryEndTime.compareTo(closeTime) > 0){
            // 查询截止时间晚于closeTime
            endTime = closeTime;
        }else {
            Date now = DateUtil.getNow();
            if (queryEndTime.compareTo(now) > 0){
                // 查询截止时间晚于当前系统时间
                endTime = now;
            }else {
                endTime = queryEndTime;
            }
        }

        // 计算照明时长，单位：秒
        Long durationLong = (endTime.getTime() - startTime.getTime()) / 1000;
        durationVO.setDurationLong(durationLong);
    }


    /**
     * 各点位消杀时长统计排名(最近7天)    查询统计各回路的累计消杀时长
     * @param query
     * @return
     */
    public List<UVLightingDurationVO> LightingDurationTopTen(UVCockpitQuery query){
        query.setCode(SpecialityModelCodeEnum.uv_lamp_control.getCode());
        query.setEndTime(DateUtil.convertToDate(LocalDateTime.now()));
        query.setStartTime(DateUtil.convertToDate(LocalDateTime.now().minusDays(7)));
        List<UVLightingDurationVO> durationVOList = cockpitMapper.queryLightingDurationDetail(query);
        if (CollUtil.isEmpty(durationVOList)){
            return null;
        }

        // 根据查询时间计算每支回路的消杀时长
        durationVOList.forEach(lightingDurationVO -> {
            checkLightingTime(lightingDurationVO, query.getStartTime(), query.getEndTime());
        });

        // 查询每个设备中，每个property的中文名称
        List<String> deviceIdList = durationVOList.stream().map(UVLightingDurationVO::getDeviceId).distinct().collect(Collectors.toList());
        // 设备id-每个property的key : 每个key的中文名称
        Map<String, String> propertyMap = buildProperty(deviceIdList);

        // 统计每支回路的消杀时长(分组求和)
        Map<String, List<UVLightingDurationVO>> map = durationVOList.stream().collect(Collectors.groupingBy(p -> p.getDeviceId() + "-" + p.getProperty()));

        List<UVLightingDurationVO> list = new ArrayList<>(map.size());
        for (Map.Entry<String, List<UVLightingDurationVO>> entry : map.entrySet()){
            UVLightingDurationVO durationVO = entry.getValue().get(0);
            UVLightingDurationVO vo = UVLightingDurationVO.builder()
                    .buildingId(durationVO.getBuildingId()).buildingName(durationVO.getBuildingName())
                    .floorId(durationVO.getFloorId()).floorName(durationVO.getFloorName())
                    .departmentItemValue(durationVO.getDepartmentItemValue()).departmentItemValueName(durationVO.getDepartmentItemValueName())
                    .roomId(durationVO.getRoomId()).roomName(durationVO.getRoomName())
                    .deviceId(durationVO.getDeviceId()).deviceName(durationVO.getDeviceName())
                    .property(durationVO.getProperty()).propertyName(propertyMap.get(entry.getKey()))
                    .build();
            // 求和，单位：秒
            Long duration = entry.getValue().stream().mapToLong(UVLightingDurationVO::getDurationLong).sum();
            // 时长单位：小时
            vo.setDuration(new BigDecimal(duration).divide(new BigDecimal(3600), 2, BigDecimal.ROUND_HALF_UP));
            list.add(vo);
        }
        // 按时长倒序查询
        list = list.stream().sorted(Comparator.comparing(UVLightingDurationVO::getDuration, Comparator.reverseOrder())).collect(Collectors.toList());
        // 取前10
        return list.subList(0, Math.min(10, list.size()));
    }





}
